package com.cdtu.outtake.service.impl;

import com.cdtu.outtake.domain.Category;
import com.cdtu.outtake.domain.Product;
import com.cdtu.outtake.domain.Shop;
import com.cdtu.outtake.dto.ShopDto;
import com.cdtu.outtake.service.ICategoryService;
import com.cdtu.outtake.service.IProductService;
import com.cdtu.outtake.service.IShopService;
import com.cdtu.outtake.service.IndexService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author : shl
 * @Date 2024/3/20 19:11
 */
@Service
@RequiredArgsConstructor
@CrossOrigin
public class IndexServiceImpl implements IndexService {
    private final IShopService shopService;
    private final ICategoryService categoryService;
    private final IProductService productService;

    private static Number orderByType(String orderType, ShopDto a, ShopDto b) {
        if ("comprehensive".equals(orderType)) {
            int aDistance = a.getDistance() == null ? 0 : a.getDistance();
            int aSales = a.getSales() == null ? 0 : a.getSales();
            double aScore = a.getScore() == null ? 0 : a.getScore();

            int bDistance = b.getDistance() == null ? 0 : b.getDistance();
            int bSales = b.getSales() == null ? 0 : b.getSales();
            double bScore = b.getScore() == null ? 0 : b.getScore();
            return (aDistance + aSales + aScore * 1500) - (bDistance + bSales + bScore * 1500);
        } else if ("distance".equals(orderType)) {
            int aDistance = a.getDistance() == null ? 0 : a.getDistance();
            int bDistance = b.getDistance() == null ? 0 : b.getDistance();
            return bDistance - aDistance;
        } else if ("sales".equals(orderType)) {
            int aSales = a.getSales() == null ? 0 : a.getSales();
            int bSales = b.getSales() == null ? 0 : b.getSales();
            return bSales - aSales;
        } else {
            double aScore = a.getScore() == null ? 0 : a.getScore();
            double bScore = b.getScore() == null ? 0 : b.getScore();
            return (bScore - aScore) * 100;
        }
    }

    @Override
    public List<ShopDto> getShops(Long schoolId, boolean dineIn, boolean takeaway, boolean offlinePickUp, String orderType) {
        List<Shop> shopList = shopService.getShopsBySchoolIdAndConditions(schoolId, null, dineIn, takeaway, offlinePickUp);
        return getShopDtoList(shopList, orderType);
    }

    public List<ShopDto> getShopDtoList(List<Shop> shopList, String orderType) {
        return shopList.stream()
                .map(shop -> {
                    ShopDto shopDto = ShopDto.toShopDto(shop);
                    List<Category> categories = categoryService.getCategoriesByShopId(shopDto.getId());
                    categories.forEach(category ->
                            category.setProducts(productService.getProductsByCategoryId(category.getId())));
                    shopDto.setCategories(categories);
                    ArrayList<Product> products = new ArrayList<>();
                    shopDto.getCategories()
                            .forEach(category -> products.addAll(category.getProducts()));
                    products.sort(Comparator.comparingInt(item -> item.getSales() == null ? 0 : item.getSales()));
                    shopDto.setProducts(products.subList(0, Math.min(3, products.size())));
                    return shopDto;
                })
                .sorted((a, b) -> orderByType(orderType, a, b).intValue())
                .collect(Collectors.toList());
    }
}
